﻿using GeneticAlgorithms.Genomes;
using GeneticAlgorithms.Tools;

namespace GeneticAlgorithms.Operators.Mutation
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="TGene">The type of the gene.</typeparam>
    public class SwapMutator<TGene> : BaseMutator<TGene>
    {
        /// <summary>
        /// Swaps the genome's genes at positions <paramref name="i"/> and <paramref name="j"/>.
        /// </summary>
        /// <param name="genome">The genome.</param>
        /// <param name="i">The i.</param>
        /// <param name="j">The j.</param>
        private static void Swap(IGenome<TGene> genome, int i, int j)
        {
            if (i != j)
            {
                TGene aux = genome[i];
                genome[i] = genome[j];
                genome[j] = aux;
            }
        }

        /// <summary>
        /// Mutates a specific gene.
        /// </summary>
        /// <param name="genome">The genome whose gene will be mutated.</param>
        /// <param name="position">The gene position.</param>
        protected override void MutateGene(IGenome<TGene> genome, int position)
        {
            int j = GeneticRandomGenerator.Default.Next(genome.Length);
            TGene previous = genome[j];

            Swap(genome, position, j);

            TraceHelper.Write("Changing gene {0} from {1} to {2} and ",
                j, previous, genome[j]);
        }
    }
}
